package com.example.rpc.demo.rpc;

import com.example.rpc.demo.discovery.ServiceDiscovery;
import com.example.rpc.demo.netty.RpcClient;
import com.example.rpc.demo.utils.ServicePathUtil;

import java.lang.reflect.Proxy;
import java.util.UUID;

public class RpcProxy {
    private ServiceDiscovery serviceDiscovery;

    public RpcProxy(ServiceDiscovery serviceDiscovery) {
        this.serviceDiscovery = serviceDiscovery;
    }

    public <T> T create(Class<?> interfaceClass) {
        return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),new Class<?>[] {interfaceClass},
                (proxy, method, args) -> {
                    RpcRequest request =  new RpcRequest();
                    request.setRequestId(UUID.randomUUID().toString());
                    request.setServiceName(ServicePathUtil.getFullName(method.getDeclaringClass()));
                    request.setMethodName(method.getName());
                    request.setParamTypes(method.getParameterTypes());
                    request.setParams(args);

                    String serviceAddress = serviceDiscovery.discover(ServicePathUtil.getFullName(method.getDeclaringClass()));
                    String[] array = serviceAddress.split(":");
                    String host = array[0];
                    int port = Integer.parseInt(array[1]);
                    RpcClient client = new RpcClient(host, port);
                    RpcResponse response = client.send(request);
                    if(response.isError()) {
                        throw response.getError();
                    }

                    return response.getResult();


                });
    }
}
